package com.tongshu.naive.chat;

import com.tongshu.naive.chat.application.UIService;
import com.tongshu.naive.chat.event.ChatEvent;
import com.tongshu.naive.chat.event.LoginEvent;
import com.tongshu.naive.chat.infrastructure.util.CacheUtil;
import com.tongshu.naive.chat.socket.NettyClient;
import com.tongshu.naive.chat.ui.view.chat.ChatController;
import com.tongshu.naive.chat.ui.view.chat.IChatMethod;
import com.tongshu.naive.chat.ui.view.login.ILoginMethod;
import com.tongshu.naive.chat.ui.view.login.LoginController;
import io.netty.channel.Channel;
import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import protocol.login.ReconnectRequest;

import java.util.concurrent.*;

public class Application extends javafx.application.Application {

    private Logger logger = LoggerFactory.getLogger(Application.class);

    // 线程池
    private static ExecutorService executorService = new ThreadPoolExecutor(2, 4, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10));
    private static ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1, new BasicThreadFactory.Builder().namingPattern("client-schedule-pool-%d").daemon(true).build());

    @Override
    public void start(Stage primaryStage) throws Exception {
        // 1. 启动窗口
        IChatMethod chat = new ChatController(new ChatEvent());
        ILoginMethod login = new LoginController(new LoginEvent(), chat);
        login.doShow();

        UIService uiService = new UIService();
        uiService.setiChatMethod(chat);
        uiService.setLoginMethod(login);

        // 2. 启动socket连接
        logger.info("NettyClient连接服务开始 inetHost：{} inetPort：{}", "127.0.0.1", 7397);
        NettyClient nettyClient = new NettyClient(uiService);
        Future<Channel> future = executorService.submit(nettyClient);
        Channel channel = future.get();
        if (null == channel) throw new RuntimeException("netty client start error channel is null");

        while (!nettyClient.isActive()) {
            logger.info("NettyClient启动服务。。。");
            TimeUnit.MILLISECONDS.sleep(500);
        }
        logger.info("NettyClient连接服务完成 {}", channel.localAddress());

        // Channel状态定时检查：3秒后每5秒执行一次
        scheduledExecutorService.scheduleAtFixedRate(() -> {
            while (!nettyClient.isActive()) {
                logger.info("通信管道巡检：通信管道状态 " + nettyClient.isActive());
                try {
                    logger.info("通信管道巡检：断线重连[Begin]");
                    Channel freshChannel = executorService.submit(nettyClient).get();
                    if (null == CacheUtil.userId) continue;
                    freshChannel.writeAndFlush(new ReconnectRequest(CacheUtil.userId));
                } catch (InterruptedException | ExecutionException e) {
                    logger.error("通信管道巡检：断线重连[Error]");
                }
            }
        }, 3, 5, TimeUnit.SECONDS);

    }

    public static void main(String[] args) {
        launch(args);
    }
}
